package ru.spb.osll.myfit.server;

import static ru.spb.osll.myfit.server.parser.PageUtils.getFullPath;

import java.io.File;
import java.io.IOException;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.client.service.FitService;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.TextParsingTools;
import ru.spb.osll.myfit.server.fixtureiterator.FileFactory;
import ru.spb.osll.myfit.server.handler.ContentHandler;
import ru.spb.osll.myfit.server.handler.Handler;
import ru.spb.osll.myfit.server.handler.PageLoader;
import ru.spb.osll.myfit.server.handler.WikiPageWriter;
import ru.spb.osll.myfit.server.parser.TableUtils;
import ru.spb.osll.myfit.server.templateloader.JarTableTemplateLoader;
import ru.spb.osll.myfit.server.templateloader.TableTemplateLoader;
import ru.spb.osll.myfit.util.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 * 
 * @author kua
 */

@SuppressWarnings("serial")
public class FitServiceImpl extends RemoteServiceServlet implements FitService {
  private Handler m_contentHandler;
  private WikiPageWriter m_pageWriter;
  private Configurator m_configurator;
  private static Logger LOG = Logger.getLogger(FitServiceImpl.class);

  public FitServiceImpl() {

    LOG.info("FitServiceImpl constructor");
    m_configurator = Configurator.getInstance();
    URLClassLoader m_classLoader = new MyFitClassLoaderFactory(new FileFactory())
        .createClassLoader(m_configurator.getJars(),
            m_configurator.getFixtures());
    TableTemplateLoader m_templateLoader = new JarTableTemplateLoader(m_configurator.getFixtures(),
        m_classLoader);
    Map<String, Class< ? >> m_fixtureClasses = m_templateLoader.getFixtureClasses();
   
    HashMap<String, Class<?>> map = new HashMap<String, Class<?>>();
    for(Class<?> clazz : m_fixtureClasses.values()){
      map.put(StringUtils.splitCamelCase(clazz.getSimpleName()), clazz);
    }
    PageLoader pageLoader = new PageLoader(new TableUtils(map));
    ImportsPrinter m_importsPrinter = new ImportsPrinter(m_fixtureClasses, m_configurator);
    m_contentHandler = new ContentHandler(m_configurator.getRoot(), pageLoader);
    m_pageWriter = new WikiPageWriter(m_importsPrinter);
    
  }

  @Override
  public Page loadPage(String path) {
    return m_contentHandler.loadPage(path);
  }

  @Override
  public Page loadPageFromTestResultsDirectory(String pagePath, String pageId) {
    String rootName = new File(m_configurator.getRoot()).getName();
    String testResultsDirectory = m_configurator.getTestResultsDirectory();
    String directory = testResultsDirectory + File.separator + pageId +
        File.separator + rootName;
    return m_contentHandler.loadPageFromDirectory(pagePath, directory);
  }

  @Override
  public void savePage(String path, Page page) {
    try {
      LOG.debug("run savePage");
      m_pageWriter.savePage(getFullPath(m_configurator.getRoot(), path),
          page);
      LOG.info("save page: " + path);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public String getPagePath() {
    LOG.debug("try get attrib \"pagePath\" ");
    String pagePath = (String) getServletContext().getAttribute(
        TextParsingTools.PAGE_PATH_ATTRIBUTE);
    LOG.debug("attrib \"pagePath\" = " + pagePath);
    getServletContext().removeAttribute(TextParsingTools.PAGE_PATH_ATTRIBUTE);

    return pagePath;
  }
}
